﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IWMAG.Scripting.AST.ObjectModel;
using IWMAG.Scripting.Types;
using IWMAG.Scripting.Interpreter;

namespace IWMAG.Scripting.AST.TerminalExpressions {
    internal class StringExpression : ConstExpression<string> {
        public StringExpression(Compiler.Lexeme l, string s) : base(l, s, CodeType.String) { }
    }

    internal class IntExpression : ConstExpression<int> {
        public IntExpression(Compiler.Lexeme l, int s) : base(l, s, CodeType.Int) { }
    }

    internal class RealExpression : ConstExpression<double> {
        public RealExpression(Compiler.Lexeme l, double s) : base(l, s, CodeType.Real) { }
    }

    internal class BoolExpression : ConstExpression<bool> {
        public BoolExpression(Compiler.Lexeme l, bool s) : base(l, s, CodeType.Bool) { }
    }

    internal class VoidExpression : CodeExpression {
        public VoidExpression(Compiler.Lexeme l) : base(l) {
        }

        public override CodeType TypeOf() {
            return CodeType.Void;
        }
    }

    internal class ConstExpression<T> : CodeExpression {
        public T Value { get; set; }
        private CodeType Type;

        public ConstExpression(Compiler.Lexeme l, T val, CodeType t) : base(l) {
            Value = val;
            Type = t;
        }

        public override CodeType TypeOf() {
            return Type;
        }

        public override IEnumerable<Continuation> ValueOf(Interpreter.ScriptEngine engine, Helpers.RuntimeTable sym, Interpreter.Reference<Interpreter.RunValue> val) {
            val.ReferencedValue.Value = Value;
            yield break;
        }
    }
}
